The use of shared resources among functional processes in a system, such as the use of shared memory within an integrated circuit, generally requires a substantial amount of data-buffering to maintain independence and isolation among the functional processes, and to minimize performance degradation caused by delayed data accesses.
A memory access controller is typically used to arbitrate or regulate access to the memory, wherein each functional process requests access as required, and the memory access controller provides the requested access. If multiple processes request simultaneous access, the memory access controller arbitrates among the requests to resolve the conflict. Furthermore, if certain processes are processing time sensitive data (e.g., video or audio streams), the memory access controller must be capable of ensuring adequate Quality of Service (QoS) for those processes.
To achieve high-speed and performance, care must be taken to assure that a requesting process does not “stall” the system by failing to complete its memory access task in a timely manner. Each process generally contains a buffer that is sufficient to hold the maximum amount of data that it might read from or write to the memory between access intervals. Typically, separate read and write buffers are used within each process to minimize conflicts and delays within the process. To facilitate writing data to the memory efficiently, the process will not request a write access to memory until the data is available to be written, or until it is certain that the data will be available by the time the write access is granted. Similarly, a read operation is not requested until the process is ready to accept the data, or until it can be predicted that it will be ready to accept the data at the time that read data is returned to the requester.
The physical and logical connection of each process's read and write buffers to a memory access controller, or directly to the memory, introduces a number of difficulties in a complex design that may contain dozens of processes that share the same memory. Tristate buses are commonly used to allow multiple devices to access a common resource, but their application is limited in scale, due to capacitive loading effects.
Hierarchical design techniques are employed to minimize the need to directly connect each functional process that shares access to a common resource to that resource. A hierarchical tree-structure is used, with the shared access to the resource, such as a memory, at the highest hierarchical level. Each upper level process has direct access the memory, via a memory access controller; each of the processes at the next lower level in the hierarchy send and receive data to and from the memory via an upper level process; and so on down through the hierarchy.
A hierarchical memory-access structure, however, generally introduces a degradation in performance and an addition in cost. If a lower level process desires to write a block of data to memory, the lower level process must communicate the block of data to the higher level process, so that the higher level process has the data available as soon as it is granted access to write the data to the memory, or access to send the data to the next level of the hierarchy. Thus, the effective data-access time for a lower level process incurs the additional time required to transfer the block of data from the lower level process to buffer at each upper level in the hierarchy. At each level of the hierarchy, a “handshaking” protocol is used to manage the transfer of the data between adjacent levels, further delaying the data-transfer process. This data-transfer process also typically requires that each upper level process contain a buffer that is as large as required by any of its lower level processes, and this buffer may be redundant to an output buffer in the lower level process that could have been used for interfacing with the memory, if this lower level process had been connected directly to the memory in a non-hierarchical manner.
A hierarchical memory-access structure may also present design difficulties from the standpoint of reconciling physical and logical constraints of the various processes coupled to the structure. Particularly in the case of memory-access structures used to connect processes on an integrated circuit chip with shared resources located on the same chip, physical layout issues may dictate a particular physical hierarchy to comply with timing constraints, e.g., by requiring processes that are located in the same physical area of a chip to be coupled to the same node in the memory-access structure to minimize line lengths. However, from the standpoint of logical design, joining unrelated processes at the same node because of timing issues may not be optimal.
As an example, in a system on chip (SOC) design including multiple complex processor cores and numerous secondary processes, it may be optimal to couple a processor core to the same node of a memory-access structure as one or more nearby secondary processes. From a logical design standpoint, however, requiring the node to arbitrate access between a high priority processor core and multiple lower priority secondary processes complicates the arbitration logic and is thus undesirable. Likewise, QoS requirements may be difficult to meet due to a lack of granularity between processes spanning multiple levels of hierarchy.
Addressing these concerns may require custom arbitration logic and/or a reworking of the physical layout of a chip to better conform the physical layout to the desired logical or functional operation of the memory-access structure. As a result, design efforts and costs are often increased, with tradeoffs made to accommodate competing physical and logical design goals.